#pragma once
#include "Buffer.h"
#include "MessageQueue.h"

namespace COMM
{
	class COMM_API MessageParser : public MessageQueue
	{
	public:
		enum ParseResult{ PR_SUCESS=0, PR_NEEDMORE, PR_ERROR};
		// HitMaxMsgSize: the max possible size of single message.
		enum{ HitMaxMsgSize = 1024*1024*10 };
		MessageParser():m_nHitMaxMsgSize(HitMaxMsgSize){}
		virtual ~MessageParser(){}
		void SetMaxMsgSize(int maxMsgSize){ m_nHitMaxMsgSize = maxMsgSize;}
		// parameter message is valid only if returned PR_SUCESS.
		virtual ParseResult Parse(/*OUT*/Buffer& message, unsigned int timeoutMs=-1) = 0;
		virtual void PackageMessage(/*OUT*/Buffer& message, const void* buffer, int size) = 0;
	protected:
		int m_nHitMaxMsgSize;
		Buffer m_tmpBuffer;
	};

	class COMM_API StreamMessageParser : public MessageParser
	{
	public:
		enum{ HeaderSize=4, CheckCodeSize=2 };
		StreamMessageParser():m_checkcode(0xFAFA){ 
			MYLIB_ASSERT( (sizeof(int)==HeaderSize) && (sizeof(m_checkcode)==CheckCodeSize) );}
		void SetCheckCode(unsigned short checkcode){ m_checkcode=checkcode; }
		// **** NOT-MTSafe ****
		ParseResult Parse(Buffer& message, unsigned int timeoutMs=-1);
		void PackageMessage(Buffer& message, const void* buffer, int size);
	private:
		unsigned short m_checkcode;
	};

	class COMM_API LineMessageParser : public MessageParser
	{
	public:
		enum{ SeparatorMaxLength=8 };
		LineMessageParser(){ SetSeparator("\r\n"); }
		void SetSeparator(const char* separator){ strncpy(m_separator,separator,SeparatorMaxLength); m_separator[SeparatorMaxLength]=0; }
		// **** NOT-MTSafe ****
		ParseResult Parse(Buffer& message, unsigned int timeoutMs=-1);
		void PackageMessage(Buffer& message, const void* buffer, int size);
	private:
		char m_separator[SeparatorMaxLength+1]; 
	};

}

